import sqlite3
from sqlite3.dbapi2 import TimeFromTicks
from BookManager import BookManager
from UserManager import UserManager
from LogManager import log_output
from typing import Dict, Tuple, List


# Shelf Database
DATABASE = 'database/shelf_data.db'


class ShelfManager:
    def __init__(self, user_manager: UserManager, book_manager: BookManager):
        self.database = DATABASE
        self.user_manager = user_manager
        self.book_manager = book_manager

        self.error_info = {
            'ok': False
        }

    def get_conn(self):
        self.conn = sqlite3.connect(self.database)
        return self.conn

    def close_conn(self):
        if self.conn is None:
            return

        try:
            self.conn.close()
        except Exception as err:
            log_output(str(err))

        self.conn = None

    def request_shelf(self, send_data: Dict[str, str]) -> Dict[str, str]:
        assert type(send_data) == dict
        assert 'token' in send_data

        token = send_data['token']
        user_id = self.user_manager.get_user_id_with_token(token)

        try:
            sql = f'SELECT book_id FROM shelf WHERE user_id = {user_id}'
            conn = self.get_conn()
            cursor = conn.cursor()
            rows = cursor.execute(sql)

            books = []
            for row in rows:
                book_id = row[0]
                book_info = self.book_manager.get_book_info(book_id)
                books.append({
                    'book_id': book_id,
                    'title': book_info.title,
                    'author': book_info.author,
                    'shortIntro': book_info.shortintro,
                    'cate': book_info.cate,
                    'cover': book_info.cover,
                    'label': '推荐'
                })

            return_dict = {
                'ok': True,
                'total': len(books),
                'books': books
            }

            return return_dict
        except Exception as err:
            log_output(str(err))
            raise ValueError()
        finally:
            if cursor is not None:
                cursor.close()
            self.close_conn()

    def modify_shelf(self, send_data: Dict[str, str]) -> Dict[str, str]:
        assert type(send_data) == dict
        assert 'token' in send_data and 'type' in send_data and 'book_id' in send_data

        token = send_data['token']
        type_id = send_data['type']
        book_id = send_data['book_id']
        user_id = self.user_manager.get_user_id_with_token(token)

        if not self.book_manager.book_id_exists(book_id):
            raise ValueError('Book id not exist')

        try:
            if type_id == 0:
                sql = f'DELETE FROM shelf WHERE user_id = {user_id} AND book_id = {book_id}'
            else:
                sql = f'INSERT INTO shelf VALUES ({user_id}, {book_id})'
            conn = self.get_conn()
            cursor = conn.cursor()
            cursor.execute(sql)
            conn.commit()

            return {'type': 0}
        except Exception as err:
            log_output(str(err))
            raise ValueError()
        finally:
            if cursor is not None:
                cursor.close()
            self.close_conn()
